import numpy as np    
from deap import base, creator, tools, algorithms    
import matplotlib.pyplot as plt    
import os    
    
# 定义成本计算函数    
def calculate_cost(decision_vars, parameters):  
    x1, x2, x3, xf, xd = decision_vars    
    p1, p2, p3, C_assemble, C_finished, C_dismantle, C_exchange, Ct1, Ct2, Ct3, n1, n2, n3, n_finished = parameters    
        
    # 零配件检测成本    
    cost_parts = x1 * Ct1 * n1 + x2 * Ct2 * n2 + x3 * Ct3 * n3    
        
    # 装配成本    
    cost_assemble = C_assemble * n_finished    
        
    # 产品检测成本    
    cost_product = xf * C_finished * n_finished    
        
    # 成品次品率计算    
    if p3 != 0:    
        p_assembly = (1 - x1) * p1 + (1 - x2) * p2 + (1 - x3) * p3 - (1 - x1) * (1 - x2) * (1 - x3) * p1 * p2 * p3    
    else:    
        p_assembly = (1 - x1) * p1 + (1 - x2) * p2 - (1 - x1) * (1 - x2) * p1 * p2    
        
    pf = 1 - (1 - p_assembly) ** 2    
        
    # 拆解和调换成本    
    cost_rework = xd * C_dismantle * pf * n_finished    
    if C_exchange != 0:    
        cost_replace = (1 - xd) * C_exchange * pf * n_finished    
    else:    
        cost_replace = 0    
        
    # 总成本    
    total_cost = cost_parts + cost_assemble + cost_product + cost_rework + cost_replace    
        
    return total_cost    
    
# 创建遗传算法个体和种群    
def create_individual_and_population(toolbox, n_variables):    
    toolbox.register("attr_bool", np.random.randint, 2)    
    toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n_variables)    
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)    
    
# 注册遗传算法操作    
def register_ga_operations(toolbox):    
    toolbox.register("mate", tools.cxTwoPoint)    
    toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)    
    toolbox.register("select", tools.selTournament, tournsize=3)    
    
# 执行遗传算法    
def run_genetic_algorithm(toolbox, population, n_gen, stats, verbose=False):    
    result, log = algorithms.eaSimple(population, toolbox, cxpb=0.7, mutpb=0.2, ngen=n_gen,    
                                     stats=stats, halloffame=None, verbose=verbose)    
    return result, log    
    
# 在全局范围内创建类    
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))    
creator.create("Individual", list, fitness=creator.FitnessMin)    
    
# 初始化并运行优化    
def optimize_cost(parameters, count):    
    toolbox = base.Toolbox()    
        
    # 创建个体和种群    
    n_variables = 5  # x1, x2, x3, xf, xd    
    create_individual_and_population(toolbox, n_variables)    
        
    # 定义适应度函数    
    def eval_cost(individual):    
        return calculate_cost(individual, parameters),    
        
    toolbox.register("evaluate", eval_cost)    
        
    # 注册遗传算法操作    
    register_ga_operations(toolbox)    
        
    # 设置种群大小和代数    
    population = toolbox.population(n=60)    
    n_gen = 50    
        
    # 初始化统计信息对象    
    stats = tools.Statistics(lambda ind: ind.fitness.values)    
    stats.register("avg", np.mean)    
    stats.register("std", np.std)    
    stats.register("min", np.min)    
    stats.register("max", np.max)    
        
    # 运行遗传算法    
    result, log = run_genetic_algorithm(toolbox, population, n_gen, stats)    
        
    # 找到最优解    
    best_individual = tools.selBest(population, k=1)[0]    
    best_cost = eval_cost(best_individual)[0]    
    print(f"Best Individual: {best_individual} (x1, x2, x3, xf, xd)")    
    print(f"Minimum Cost: {best_cost}")    
        
    # 绘制迭代图    
    generations = log.select("gen")    
    avg_costs = log.select("avg")    
        
    plt.figure(figsize=(10, 6))    
    plt.plot(generations, avg_costs, marker='o', linestyle='-', color='b')    
    plt.title('Average Cost per Generation')    
    plt.xlabel('Generation')    
    plt.ylabel('Average Cost')    
    plt.grid(True)    
        
    # 确保输出文件夹存在    
    output_dir = 'test3_genetic_picture'    
    if not os.path.exists(output_dir):    
        os.makedirs(output_dir)    
        
    # 保存图片到指定文件夹    
    plt.savefig(os.path.join(output_dir, f'average_cost_per_generation{count}.png'))    
    plt.close()    
    
# 调用优化函数    
parameters_list = [    
    (0.1, 0.1, 0.1, 8, 4, 6, 0, 1, 1, 2, 100, 100, 100, 90),    
    (0.1, 0.1, 0.1, 8, 4, 6, 0, 1, 1, 2, 100, 100, 100, 90),    
    (0.1, 0.1, 0, 8, 4, 6, 0, 1, 2, 0, 100, 100, 0, 90),    
    (0.1, 0.1, 0.1, 8, 6, 10, 40, 4, 4, 4, 90, 90, 90, 81)    
]    
  
# 调用优化函数    
for index, parameters in enumerate(parameters_list, start=1):    
    optimize_cost(parameters, index)